package com.tianluo.tianluobookstore.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.tianluo.tianluobookstore.config.AlipayConfig;
import com.tianluo.tianluobookstore.enums.OrderStatus;
import com.tianluo.tianluobookstore.enums.PaymentStatus;
import com.tianluo.tianluobookstore.request.AliPayRequest;
import com.tianluo.tianluobookstore.service.AliPayService;
import com.tianluo.tianluobookstore.service.OrderService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/alipay")
@Slf4j
public class AliPayController {

    @Autowired
    private AliPayService aliPayService;

    @Value("${alipay.public-key}")
    private String alipayPublicKey;

    @Value("${alipay.app-id}")
    private String appId;

    @Autowired
    private OrderService orderService;

    @PostMapping("/createOrder")
    public String createOrder(@ModelAttribute AliPayRequest aliPayRequest, Model model) throws Exception {

        System.out.println("aliPayRequest:" + aliPayRequest);

        String orderId = aliPayRequest.getOutTradeNo();
        BigDecimal totalAmount = new BigDecimal(aliPayRequest.getTotalAmount());

        String paymentForm = aliPayService.createOrder(orderId, totalAmount, "网上书店订单");
        model.addAttribute("paymentForm", paymentForm);
        return "payment";
    }

    @GetMapping("/return")
    public String returnUrl(HttpServletRequest request, Model model) {
        // 处理支付宝同步通知同步通知
        System.out.println("同步通知");
        model.addAttribute("result", "支付成功");

        return "result";
    }

    @PostMapping("/notify")
    public String notifyUrl(HttpServletRequest request) throws Exception {
        // 1. 将请求参数转换为Map
        Map<String, String> params = convertRequestParamsToMap(request);
        log.info("收到支付宝异步通知, 参数: {}", params);
        // 处理支付宝异步通知
        System.out.println("异步通知");

        // 3. 验证通知的app_id是否与当前应用一致
        if (!appId.equals(params.get("app_id"))) {
            log.error("支付宝异步通知app_id不匹配");
            return "failure";
        }

        // 4. 处理业务逻辑
        String tradeStatus = params.get("trade_status");
        if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
            // 获取商户订单号
            String orderId = params.get("out_trade_no");
            // 支付宝交易号
            String tradeNo = params.get("trade_no");

            // 5. 幂等性检查：查询订单状态，避免重复处理
            if (!orderService.isOrderPaid(orderId)) {
                // 6. 更新订单状态为已支付（实现你的业务逻辑）
                int result = orderService.updateOrderStatus(orderId, OrderStatus.WAIT_SENDING.getCode(),
                        OrderStatus.PENDING.getCode(),
                        PaymentStatus.PAID.getCode(), PaymentStatus.NOT_PAID.getCode());
                if (result > 0) {
                    log.info("订单支付成功:  orderId={}", orderId);
                }else {
                    log.warn("订单状态更新失败,orderId={}", orderId);
                }

            } else {
                log.warn("订单已处理，忽略重复通知: orderId={}", orderId);
            }
        }

        return "success";
    }

    /**
     * 将HttpServletRequest中的参数转换为Map
     */
    private Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();

        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        return params;
    }
}
